package io.coderyeah.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.coderyeah.basic.Result;
import io.coderyeah.basic.constant.Constants;
import io.coderyeah.basic.exception.BusinessException;
import io.coderyeah.user.domain.LoginInfo;
import io.coderyeah.user.domain.User;
import io.coderyeah.user.dto.UserDTO;
import io.coderyeah.user.mapper.LoginInfoMapper;
import io.coderyeah.user.mapper.UserMapper;
import io.coderyeah.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private JavaMailSender javaMailSender;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LoginInfoMapper loginInfoMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Transactional
    @Override
    public Result register(UserDTO userDTO) throws MessagingException {
        // 1.新增User信息 默认状态为0禁用 须通过邮件激活
        final User user = new User();
        // 设置用户邮箱
        user.setEmail(userDTO.getEmail());
        // 随机获取盐值
        final String salt = RandomUtil.randomString(32);
        user.setSalt(salt);
        // 密码加密MD5
        user.setPassword(DigestUtil.md5Hex(salt + userDTO.getPassword()));
        // 设置状态
        user.setState(0);
        userMapper.insert(user);
        // 2.发送邮件激活用户-修改状态为1 启用
        final MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        final MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        helper.setFrom("2399690261@qq.com");
        helper.setSubject("用注册激活");
        helper.setText("<h3>您的邮箱注册已送达，请<a href='http://localhost:8080/user/active/" + user.getId() + "'><font color='blue'>点击这里</font></a>激活邮件</h3>", true);
        helper.setTo(userDTO.getEmail());
        javaMailSender.send(mimeMessage);
        return Result.success(null);
    }

    @Transactional
    @Override
    public Result active(String id) {
        final User user = userMapper.selectById(id);
        // 1.添加用户登录信息
        final LoginInfo loginInfo = BeanUtil.copyProperties(user, LoginInfo.class);
        loginInfo.setDisable(true);
        loginInfo.setType(1);// 用户
        loginInfoMapper.insert(loginInfo);
        // 2.修改用户状态为1 修改外键
        user.setState(1);
        user.setLogininfoId(loginInfo.getId());
        userMapper.updateById(user);
        return Result.success("邮箱注册激活成功");
    }

    @Transactional
    @Override
    public void registerByPhone(UserDTO userDTO) {
        // 校验参数是否为空
        if (StrUtil.isBlank(userDTO.getPassword()) ||
                StrUtil.isBlank(userDTO.getPasswordRepeat()) ||
                StrUtil.isBlank(userDTO.getPhone()) ||
                StrUtil.isBlank(userDTO.getPhoneCode())) {
            throw new BusinessException("数据不能为空!请输入相关数据!");
        }
        // 短信验证码是否过期
        final String value = stringRedisTemplate.opsForValue().get(Constants.USER_REGISTER_PHONE_PREFIX + userDTO.getPhone());
        if (value == null) {
            throw new BusinessException("验证码已过期,请重新获取");
        }
        // 判断验证码是否输入正确
        if (!userDTO.getPhoneCode().equals(value.split(":")[0])) {
            throw new BusinessException("验证码输入错误！");
        }
        if (!userDTO.getPassword().equals(userDTO.getPasswordRepeat())) {
            throw new BusinessException("密码不一致,请重新输入！");
        }
        // 新增登录用户
        addUser(userDTO);
    }

    private void addUser(UserDTO userDTO) {
        final LoginInfo loginInfo = addLoginInfo(userDTO);
        // 新增user用户
        final User user = BeanUtil.copyProperties(loginInfo, User.class);
        user.setLogininfoId(loginInfo.getId());
        user.setState(1);
        userMapper.insert(user);
    }

    private LoginInfo addLoginInfo(UserDTO userDTO) {
        final LoginInfo loginInfo = BeanUtil.copyProperties(userDTO, LoginInfo.class);
        loginInfo.setType(1); // 普通用户
        loginInfo.setDisable(true); // 启用
        // 加盐加密
        final String salt = RandomUtil.randomString(32);
        loginInfo.setSalt(salt);
        loginInfo.setPassword(DigestUtil.md5Hex(salt + userDTO.getPassword()));
        loginInfoMapper.insert(loginInfo);
        return loginInfo;
    }
}
